package cn.zhoujing.security.demo.service.impl;

import cn.zhoujing.security.demo.common.consts.RedisConst;
import cn.zhoujing.security.demo.common.properties.JwtProperties;
import cn.zhoujing.security.demo.common.utils.JwtProvider;
import cn.zhoujing.security.demo.common.utils.RedisUtil;
import cn.zhoujing.security.demo.dto.LoginDTO;
import cn.zhoujing.security.demo.entity.UserDetail;
import cn.zhoujing.security.demo.vo.AccessToken;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.zhoujing.security.demo.entity.User;
import cn.zhoujing.security.demo.service.UserService;
import cn.zhoujing.security.demo.mapper.UserMapper;
import jakarta.annotation.Resource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

/**
 * @author JingZhou
 * @description 针对表【user(用户表)】的数据库操作Service实现
 * @createDate 2024-02-07 18:11:08
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {

    @Resource
    private AuthenticationManager authenticationManager;

    @Resource
    private JwtProvider jwtProvider;

    @Resource
    private JwtProperties jwtProperties;

    @Resource
    private RedisUtil redisUtil;


    @Override
    public AccessToken login(LoginDTO dto) {
        // 创建 UsernamePasswordAuthenticationToken 构建认证参数
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(dto.getId(), dto.getPassword());
        // 由Spring Security帮我们进行密码校验
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        // 将认证信息存储至ThreadLocal
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(authenticate);
        SecurityContextHolder.setContext(context);
        // 创建Token
        UserDetail userDetail = (UserDetail) authenticate.getPrincipal();
        AccessToken token = jwtProvider.createToken(userDetail);
        // 写入缓存
        String userId = userDetail.getUsername();
        redisUtil.set(RedisConst.userLoginInfoKeyBuild(userId), JSON.toJSONString(token), jwtProperties.getExpirationTime());
        redisUtil.set(RedisConst.userDetailInfoKeyBuild(userId), JSON.toJSONString(userDetail), jwtProperties.getExpirationTime());

        return token;
    }

}




